package result

import (
	"context"
	"fmt"
	"strings"

	"gitee.com/bjf-fhe/apicat/entry"
	"gitee.com/bjf-fhe/apicat/entry/etype"
	"github.com/sirupsen/logrus"
)

type Stat struct {
	Brief       Brief
	ClientCount int
	Clients     map[string]*ClientStat
	Detail      []*entry.LogEntry
	Ctx         context.Context
}

type ClientStat struct {
	LegalCount      int              `json:"l"`
	IllegalCount    int              `json:"i"`
	MaxIllegalLevel etype.EntryError `json:"m"`
}

func (c *ClientStat) AddStat(ee etype.EntryError) {
	c.IllegalCount++
	if c.MaxIllegalLevel < ee {
		c.MaxIllegalLevel = ee
	}
}

type StatReader interface {
	GetTotal() int64
	GetDetail() string
}

//用于统计的Handler，实现了Handler接口
func NewStat(ctx context.Context) *Stat {
	var stat Stat
	stat.Clients = make(map[string]*ClientStat)
	stat.Brief = make(Brief)
	stat.Ctx = ctx
	return &stat
}

func (stat *Stat) GetTotal() int64 {
	return stat.Brief.Total()
}

func (stat *Stat) GetDetail() string {
	return stat.Brief.Detail()
}

func (stat *Stat) RecordEntry(en *entry.LogEntry) error {
	stat.Detail = append(stat.Detail, en)
	clientStat := stat.Clients[en.Client]
	if clientStat == nil {
		clientStat = new(ClientStat)
	}
	clientStat.AddStat(en.ErrorType)
	if clientStat != nil {
		stat.Clients[en.Client] = clientStat
	}
	stat.Brief.AddCountFor(en.ErrorType)
	return nil
}

func (stat *Stat) Sum() {
	stat.ClientCount = len(stat.Clients)
}

func (stat *Stat) RecordError(err error) error {
	//TODO record error
	logrus.WithError(err).Error("RecordError")
	return nil
}

type Brief map[etype.EntryError]int64

func (s *Brief) AddCountFor(typ etype.EntryError) {
	if total, ok := (*s)[typ]; ok {
		(*s)[typ] = total + 1
	} else {
		(*s)[typ] = 1
	}
}

func (s *Brief) Total() int64 {
	var total int64
	for _, v := range *s {
		total += v
	}
	return total
}

func (s *Brief) Detail() string {
	var counts []string
	for k, v := range *s {
		counts = append(counts, fmt.Sprintf("%v: %d", k, v))
	}
	return strings.Join(counts, "\n")
}
